import { Button, DatePicker, Select, Table } from "antd";
import SearchIcon from "@/assets/icons/search.svg?jsx";
import useFetch from "@/lib/hooks/useFetch";
import { getDeviceList } from "@/lib/api/device";
import { useAtomValue } from "jotai";
import { tokenAtom } from "@/store/user";
import { useState } from "react";
import useOnMounted from "@/lib/hooks/useOnMounted";
import { useMessage } from "@/providers/AntdMessageProvider";
import useOnUpdated from "@/lib/hooks/useOnUpdated";
import {
  getDeviceRunningStatusAsExcel,
  getDeviceRunningStatusList,
} from "@/lib/api/deviceStatus";
import getRequestErrorMessage from "@/lib/utils/getRequestErrorMessage";
import { useNavigate, useSearchParams } from "react-router";
import dayjs, { Dayjs } from "dayjs";

export default function History() {
  const [searchData, setSearchData] = useState({
    device: undefined as number | undefined,
    time: null as string[] | null,
  });
  const token = useAtomValue(tokenAtom);
  const [pagination, setPagination] = useState({
    index: 1,
    size: 10,
    total: 0,
  });
  const [backBtnVisible, setBackBtnVisible] = useState(false);
  const navigate = useNavigate();
  const [search] = useSearchParams();

  const message = useMessage();
  const {
    isLoading: isDeviceListLoading,
    data: deviceList,
    refetch: loadDeviceList,
    cancel: cancelLoadDeviceList,
  } = useFetch({
    fetchFn: (
      payload: { pageNum: number; pageSize: number },
      signal: AbortSignal,
    ) =>
      getDeviceList(payload, token, signal).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
        return res.rows;
      }),
  });

  const {
    data: list,
    isLoading: isListLoading,
    refetch: loadList,
    cancel: cancelLoadList,
  } = useFetch({
    fetchFn: (
      data: Parameters<typeof getDeviceRunningStatusList>[0],
      signal: AbortSignal,
    ) =>
      getDeviceRunningStatusList(data, token, signal).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
        setPagination((p) => ({ ...p, total: res.total }));
        return res.rows;
      }),
  });

  const { isLoading: isExportLoading, refetch: exportAsExcel } = useFetch({
    fetchFn: (data: Parameters<typeof getDeviceRunningStatusList>[0]) =>
      getDeviceRunningStatusAsExcel(data, token),
    onError(error) {
      message.error(getRequestErrorMessage(error, "导出失败！"));
    },
    onSuccess(data) {
      const deviceName = deviceList!.find(
        (device) => device.deviceId === searchData.device,
      )!.deviceName;
      const url = URL.createObjectURL(data);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${deviceName}-${searchData.time!.join("-")}.xlsx`;
      a.click();
      URL.revokeObjectURL(url);
    },
  });

  // 返回到图标页
  function handleGoBack() {
    const deviceId = search.get("deviceId");
    const date = search.get("date")?.split(",");
    if (backBtnVisible && deviceId && date) {
      sessionStorage.setItem(
        "history-chart-view-condition",
        JSON.stringify({ date }),
      );
      navigate({ pathname: `/dashboard/${deviceId}`, search: "?view=charts" });
    }
  }

  function getSearchParams(
    params?: Partial<Parameters<typeof loadList>[0]>,
  ): Parameters<typeof loadList>[0] {
    return {
      pageNum: pagination.index,
      pageSize: pagination.size,
      deviceId: searchData.device,
      "readTime.start": searchData.time?.[0],
      "readTime.end": searchData.time?.[1],
      ...params,
    };
  }

  function handleSearch(type: "search" | "export", params = getSearchParams()) {
    if (!params.deviceId) {
      message.error("请选择设备！");
      return;
    }
    if (!params["readTime.start"] || !params["readTime.end"]) {
      message.error("请选择时间范围！");
      return;
    }
    if (type === "search") {
      loadList(params);
    } else {
      exportAsExcel(params);
    }
  }

  useOnMounted(() => {
    loadDeviceList({ pageNum: 1, pageSize: 999 });
    const deviceId = parseInt(search.get("deviceId") || "");
    const viewDateRange = search.get("date")?.split(",");
    if (!Number.isNaN(deviceId) && viewDateRange?.length === 2) {
      const decodedDate = viewDateRange.map((item) => decodeURIComponent(item));
      setSearchData({
        device: deviceId,
        time: decodedDate,
      });
      setBackBtnVisible(true);
      handleSearch(
        "search",
        getSearchParams({
          deviceId,
          "readTime.start": decodedDate[0],
          "readTime.end": decodedDate[1],
        }),
      );
    }

    return () => {
      cancelLoadList();
      cancelLoadDeviceList();
    };
  });

  return (
    <div className="flex h-full flex-col bg-[#090909] px-10 pt-12">
      <div className="flex flex-none justify-center gap-x-4">
        {backBtnVisible && <Button onClick={handleGoBack}>返回</Button>}
        <Select
          loading={isDeviceListLoading}
          value={searchData.device}
          style={{ width: 200 }}
          onChange={(v) => setSearchData((p) => ({ ...p, device: v }))}
          allowClear
          showSearch
          optionFilterProp="label"
          placeholder="选择设备"
        >
          {deviceList?.map((device) => (
            <Select.Option
              key={device.deviceId}
              label={device.deviceName}
              value={device.deviceId}
            >
              {device.deviceName}
            </Select.Option>
          ))}
        </Select>
        <DatePicker.RangePicker
          showTime
          value={
            searchData.time
              ? (searchData.time.map((s) => dayjs(s)) as [Dayjs, Dayjs])
              : null
          }
          onChange={(v) =>
            setSearchData((p) => ({
              ...p,
              time:
                v && v[0] && v[1]
                  ? [
                      v[0].format("YYYY-MM-DD HH:mm:ss"),
                      v[1].format("YYYY-MM-DD HH:mm:ss"),
                    ]
                  : null,
            }))
          }
        />
        <Button
          loading={isListLoading}
          onClick={() => {
            setPagination((p) => ({ ...p, index: 1 }));
            handleSearch("search", getSearchParams({ pageNum: 1 }));
          }}
        >
          <SearchIcon />
        </Button>
        <Button
          loading={isExportLoading}
          onClick={() => handleSearch("export")}
        >
          导出
        </Button>
      </div>
      <div className="mt-8 min-h-0 flex-auto overflow-auto">
        <Table
          dataSource={list || []}
          loading={isListLoading}
          rowKey={(row) => row.sampleTime}
          pagination={{
            total: pagination.total,
            pageSize: pagination.size,
            current: pagination.index,
            position: ["bottomRight"],
            onChange(index, size) {
              index = pagination.size === size ? index : 1;
              setPagination((p) => ({ ...p, index, size }));
              handleSearch(
                "search",
                getSearchParams({ pageNum: index, pageSize: size }),
              );
            },
          }}
        >
          <Table.Column title="编号" dataIndex="deviceId" />
          <Table.Column title="设备名称" dataIndex="deviceName" />
          <Table.Column title="时间" dataIndex="sampleTime" />
          <Table.Column title="温度" dataIndex="tPv" />
          <Table.Column title="湿度" dataIndex="hPv" />
          <Table.Column title="压力" dataIndex="pPv" />
          {/* <Table.Column title="" /> */}
        </Table>
      </div>
    </div>
  );
}
